home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 2005 March / Macworld CD March 2005 - Marathon Trilogy.iso / Shareware World / iPod / iPodderX.sit / iPodderX / iPodderX.app / Contents / Resources / RawServer.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2005-01-07  |  23.4 KB  |  797 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.3)
  3.  
  4. from bisect import insort
  5. import socket
  6. from cStringIO import StringIO
  7. from traceback import print_exc
  8. from errno import EWOULDBLOCK, ENOBUFS
  9.  
  10. try:
  11.     from select import poll, error, POLLIN, POLLOUT, POLLERR, POLLHUP
  12.     timemult = 1000
  13. except ImportError:
  14.     from selectpoll import poll, error, POLLIN, POLLOUT, POLLERR, POLLHUP
  15.     timemult = 1
  16.  
  17. from threading import Thread, Event
  18. from time import time, sleep
  19. import sys
  20. from random import randrange
  21. all = POLLIN | POLLOUT
  22.  
  23. class SingleSocket:
  24.     
  25.     def __init__(self, raw_server, sock, handler):
  26.         self.raw_server = raw_server
  27.         self.socket = sock
  28.         self.handler = handler
  29.         self.buffer = []
  30.         self.last_hit = time()
  31.         self.fileno = sock.fileno()
  32.         self.connected = False
  33.  
  34.     
  35.     def get_ip(self):
  36.         
  37.         try:
  38.             return self.socket.getpeername()[0]
  39.         except socket.error:
  40.             return 'no connection'
  41.  
  42.  
  43.     
  44.     def close(self):
  45.         sock = self.socket
  46.         self.socket = None
  47.         self.buffer = []
  48.         del self.raw_server.single_sockets[self.fileno]
  49.         self.raw_server.poll.unregister(sock)
  50.         sock.close()
  51.  
  52.     
  53.     def shutdown(self, val):
  54.         self.socket.shutdown(val)
  55.  
  56.     
  57.     def is_flushed(self):
  58.         return len(self.buffer) == 0
  59.  
  60.     
  61.     def write(self, s):
  62.         if not self.socket is not None:
  63.             raise AssertionError
  64.         self.buffer.append(s)
  65.         if len(self.buffer) == 1:
  66.             self.try_write()
  67.         
  68.  
  69.     
  70.     def try_write(self):
  71.         if self.connected:
  72.             
  73.             try:
  74.                 while self.buffer != []:
  75.                     amount = self.socket.send(self.buffer[0])
  76.                     if amount != len(self.buffer[0]):
  77.                         if amount != 0:
  78.                             self.buffer[0] = self.buffer[0][amount:]
  79.                         
  80.                         break
  81.                     
  82.                     del self.buffer[0]
  83.             except socket.error:
  84.                 e = None
  85.                 (code, msg) = e
  86.                 if code != EWOULDBLOCK:
  87.                     self.raw_server.dead_from_write.append(self)
  88.                     return None
  89.                 
  90.             except:
  91.                 code != EWOULDBLOCK
  92.             
  93.  
  94.         None<EXCEPTION MATCH>socket.error
  95.         if self.buffer == []:
  96.             self.raw_server.poll.register(self.socket, POLLIN)
  97.         else:
  98.             self.raw_server.poll.register(self.socket, all)
  99.  
  100.  
  101.  
  102. def default_error_handler(x):
  103.     print x
  104.  
  105.  
  106. class RawServer:
  107.     
  108.     def __init__(self, doneflag, timeout_check_interval, timeout, noisy = True, errorfunc = default_error_handler, maxconnects = 55):
  109.         self.timeout_check_interval = timeout_check_interval
  110.         self.timeout = timeout
  111.         self.poll = poll()
  112.         self.single_sockets = { }
  113.         self.dead_from_write = []
  114.         self.doneflag = doneflag
  115.         self.noisy = noisy
  116.         self.errorfunc = errorfunc
  117.         self.maxconnects = maxconnects
  118.         self.funcs = []
  119.         self.unscheduled_tasks = []
  120.         self.add_task(self.scan_for_timeouts, timeout_check_interval)
  121.  
  122.     
  123.     def add_task(self, func, delay):
  124.         self.unscheduled_tasks.append((func, delay))
  125.  
  126.     
  127.     def scan_for_timeouts(self):
  128.         self.add_task(self.scan_for_timeouts, self.timeout_check_interval)
  129.         t = time() - self.timeout
  130.         tokill = []
  131.         for s in self.single_sockets.values():
  132.             if s.last_hit < t:
  133.                 tokill.append(s)
  134.                 continue
  135.         
  136.         for k in tokill:
  137.             if k.socket is not None:
  138.                 self._close_socket(k)
  139.                 continue
  140.         
  141.  
  142.     
  143.     def bind(self, port, bind = '', reuse = False):
  144.         self.bindaddr = bind
  145.         server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  146.         if reuse:
  147.             server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  148.         
  149.         server.setblocking(0)
  150.         
  151.         try:
  152.             server.setsockopt(socket.IPPROTO_IP, socket.IP_TOS, 32)
  153.         except:
  154.             pass
  155.  
  156.         server.bind((bind, port))
  157.         server.listen(5)
  158.         self.poll.register(server, POLLIN)
  159.         self.server = server
  160.  
  161.     
  162.     def start_connection(self, dns, handler = None):
  163.         if handler is None:
  164.             handler = self.handler
  165.         
  166.         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  167.         sock.setblocking(0)
  168.         sock.bind((self.bindaddr, 0))
  169.         
  170.         try:
  171.             sock.connect_ex(dns)
  172.         except socket.error:
  173.             raise 
  174.         except Exception:
  175.             e = None
  176.             raise socket.error(str(e))
  177.  
  178.         self.poll.register(sock, POLLIN)
  179.         s = SingleSocket(self, sock, handler)
  180.         self.single_sockets[sock.fileno()] = s
  181.         return s
  182.  
  183.     
  184.     def handle_events(self, events):
  185.         for sock, event in events:
  186.             if sock == self.server.fileno():
  187.                 pass
  188.             None if event & (POLLHUP | POLLERR) != 0 else None<EXCEPTION MATCH>socket.error
  189.             s = self.single_sockets.get(sock)
  190.             if s is None:
  191.                 continue
  192.             
  193.             s.connected = True
  194.             if event & (POLLHUP | POLLERR) != 0:
  195.                 self._close_socket(s)
  196.                 continue
  197.             
  198.             if event & POLLIN != 0:
  199.                 
  200.                 try:
  201.                     s.last_hit = time()
  202.                     data = s.socket.recv(100000)
  203.                     if data == '':
  204.                         self._close_socket(s)
  205.                     else:
  206.                         s.handler.data_came_in(s, data)
  207.                 except socket.error:
  208.                     e = None
  209.                     (code, msg) = e
  210.                     if code != EWOULDBLOCK:
  211.                         self._close_socket(s)
  212.                         continue
  213.                     
  214.                 except:
  215.                     code != EWOULDBLOCK
  216.                 
  217.  
  218.             None<EXCEPTION MATCH>socket.error
  219.             if event & POLLOUT != 0 and s.socket is not None and not s.is_flushed():
  220.                 s.try_write()
  221.                 if s.is_flushed():
  222.                     s.handler.connection_flushed(s)
  223.                 
  224.             s.is_flushed()
  225.         
  226.  
  227.     
  228.     def pop_unscheduled(self):
  229.         
  230.         try:
  231.             while True:
  232.                 (func, delay) = self.unscheduled_tasks.pop()
  233.                 insort(self.funcs, (time() + delay, func))
  234.         except IndexError:
  235.             pass
  236.  
  237.  
  238.     
  239.     def listen_forever(self, handler):
  240.         self.handler = handler
  241.         
  242.         try:
  243.             while not self.doneflag.isSet():
  244.                 
  245.                 try:
  246.                     self.pop_unscheduled()
  247.                     if len(self.funcs) == 0:
  248.                         period = 2 ** 30
  249.                     else:
  250.                         period = self.funcs[0][0] - time()
  251.                     if period < 0:
  252.                         period = 0
  253.                     
  254.                     events = self.poll.poll(period * timemult)
  255.                     if self.doneflag.isSet():
  256.                         return None
  257.                     
  258.                     while len(self.funcs) > 0 and self.funcs[0][0] <= time():
  259.                         (garbage, func) = self.funcs[0]
  260.                         del self.funcs[0]
  261.                         
  262.                         try:
  263.                             func()
  264.                         continue
  265.                         except KeyboardInterrupt:
  266.                             return None
  267.                             continue
  268.                             if self.noisy:
  269.                                 data = StringIO()
  270.                                 print_exc(file = data)
  271.                                 self.errorfunc(data.getvalue())
  272.                             
  273.                         
  274.  
  275.                         None<EXCEPTION MATCH>KeyboardInterrupt
  276.                     self._close_dead()
  277.                     self.handle_events(events)
  278.                     if self.doneflag.isSet():
  279.                         return None
  280.                     
  281.                     self._close_dead()
  282.                 continue
  283.                 except error:
  284.                     e = None
  285.                     if self.doneflag.isSet():
  286.                         return None
  287.                     
  288.                     
  289.                     try:
  290.                         (code, msg, desc) = e
  291.                     except:
  292.                         
  293.                         try:
  294.                             (code, msg) = e
  295.                         code = ENOBUFS
  296.  
  297.  
  298.                     if code == ENOBUFS:
  299.                         self.errorfunc('Have to exit due to the TCP stack flaking out')
  300.                         return None
  301.                     
  302.                     code == ENOBUFS
  303.                     except KeyboardInterrupt:
  304.                         return None
  305.                         continue
  306.                         data = StringIO()
  307.                         print_exc(file = data)
  308.                         self.errorfunc(data.getvalue())
  309.                         continue
  310.                     
  311.                     None<EXCEPTION MATCH>KeyboardInterrupt
  312.                 for ss in self.single_sockets.values():
  313.                     ss.close()
  314.                 
  315.  
  316.             self.server.close()
  317.             return None
  318.  
  319.  
  320.     
  321.     def _close_dead(self):
  322.         while len(self.dead_from_write) > 0:
  323.             old = self.dead_from_write
  324.             self.dead_from_write = []
  325.             for s in old:
  326.                 if s.socket is not None:
  327.                     self._close_socket(s)
  328.                     continue
  329.             
  330.  
  331.     
  332.     def _close_socket(self, s):
  333.         sock = s.socket.fileno()
  334.         s.socket.close()
  335.         self.poll.unregister(sock)
  336.         del self.single_sockets[sock]
  337.         s.socket = None
  338.         s.handler.connection_lost(s)
  339.  
  340.  
  341.  
  342. class DummyHandler:
  343.     
  344.     def __init__(self):
  345.         self.external_made = []
  346.         self.data_in = []
  347.         self.lost = []
  348.  
  349.     
  350.     def external_connection_made(self, s):
  351.         self.external_made.append(s)
  352.  
  353.     
  354.     def data_came_in(self, s, data):
  355.         self.data_in.append((s, data))
  356.  
  357.     
  358.     def connection_lost(self, s):
  359.         self.lost.append(s)
  360.  
  361.     
  362.     def connection_flushed(self, s):
  363.         pass
  364.  
  365.  
  366.  
  367. def sl(rs, handler, port):
  368.     rs.bind(port)
  369.     Thread(target = rs.listen_forever, args = [
  370.         handler]).start()
  371.  
  372.  
  373. def loop(rs):
  374.     x = []
  375.     
  376.     def r(rs = rs, x = x):
  377.         rs.add_task(x[0], 0.10000000000000001)
  378.  
  379.     x.append(r)
  380.     rs.add_task(r, 0.10000000000000001)
  381.  
  382. beginport = 5000 + randrange(10000)
  383.  
  384. def test_starting_side_close():
  385.     
  386.     try:
  387.         fa = Event()
  388.         fb = Event()
  389.         da = DummyHandler()
  390.         sa = RawServer(fa, 100, 100)
  391.         loop(sa)
  392.         sl(sa, da, beginport)
  393.         db = DummyHandler()
  394.         sb = RawServer(fb, 100, 100)
  395.         loop(sb)
  396.         sl(sb, db, beginport + 1)
  397.         sleep(0.5)
  398.         ca = sa.start_connection(('127.0.0.1', beginport + 1))
  399.         sleep(1)
  400.         if not da.external_made == []:
  401.             raise AssertionError
  402.         if not da.data_in == []:
  403.             raise AssertionError
  404.         if not da.lost == []:
  405.             raise AssertionError
  406.         if not len(db.external_made) == 1:
  407.             raise AssertionError
  408.         cb = db.external_made[0]
  409.         del db.external_made[:]
  410.         if not db.data_in == []:
  411.             raise AssertionError
  412.         if not db.lost == []:
  413.             raise AssertionError
  414.         ca.write('aaa')
  415.         cb.write('bbb')
  416.         sleep(1)
  417.         if not da.external_made == []:
  418.             raise AssertionError
  419.         if not da.data_in == [
  420.             (ca, 'bbb')]:
  421.             raise AssertionError
  422.         del da.data_in[:]
  423.         if not da.lost == []:
  424.             raise AssertionError
  425.         if not db.external_made == []:
  426.             raise AssertionError
  427.         if not db.data_in == [
  428.             (cb, 'aaa')]:
  429.             raise AssertionError
  430.         del db.data_in[:]
  431.         if not db.lost == []:
  432.             raise AssertionError
  433.         ca.write('ccc')
  434.         cb.write('ddd')
  435.         sleep(1)
  436.         if not da.external_made == []:
  437.             raise AssertionError
  438.         if not da.data_in == [
  439.             (ca, 'ddd')]:
  440.             raise AssertionError
  441.         del da.data_in[:]
  442.         if not da.lost == []:
  443.             raise AssertionError
  444.         if not db.external_made == []:
  445.             raise AssertionError
  446.         if not db.data_in == [
  447.             (cb, 'ccc')]:
  448.             raise AssertionError
  449.         del db.data_in[:]
  450.         if not db.lost == []:
  451.             raise AssertionError
  452.         ca.close()
  453.         sleep(1)
  454.         if not da.external_made == []:
  455.             raise AssertionError
  456.         if not da.data_in == []:
  457.             raise AssertionError
  458.         if not da.lost == []:
  459.             raise AssertionError
  460.         if not db.external_made == []:
  461.             raise AssertionError
  462.         if not db.data_in == []:
  463.             raise AssertionError
  464.         if not db.lost == [
  465.             cb]:
  466.             raise AssertionError
  467.         del db.lost[:]
  468.     finally:
  469.         fa.set()
  470.         fb.set()
  471.  
  472.  
  473.  
  474. def test_receiving_side_close():
  475.     
  476.     try:
  477.         da = DummyHandler()
  478.         fa = Event()
  479.         sa = RawServer(fa, 100, 100)
  480.         loop(sa)
  481.         sl(sa, da, beginport + 2)
  482.         db = DummyHandler()
  483.         fb = Event()
  484.         sb = RawServer(fb, 100, 100)
  485.         loop(sb)
  486.         sl(sb, db, beginport + 3)
  487.         sleep(0.5)
  488.         ca = sa.start_connection(('127.0.0.1', beginport + 3))
  489.         sleep(1)
  490.         if not da.external_made == []:
  491.             raise AssertionError
  492.         if not da.data_in == []:
  493.             raise AssertionError
  494.         if not da.lost == []:
  495.             raise AssertionError
  496.         if not len(db.external_made) == 1:
  497.             raise AssertionError
  498.         cb = db.external_made[0]
  499.         del db.external_made[:]
  500.         if not db.data_in == []:
  501.             raise AssertionError
  502.         if not db.lost == []:
  503.             raise AssertionError
  504.         ca.write('aaa')
  505.         cb.write('bbb')
  506.         sleep(1)
  507.         if not da.external_made == []:
  508.             raise AssertionError
  509.         if not da.data_in == [
  510.             (ca, 'bbb')]:
  511.             raise AssertionError
  512.         del da.data_in[:]
  513.         if not da.lost == []:
  514.             raise AssertionError
  515.         if not db.external_made == []:
  516.             raise AssertionError
  517.         if not db.data_in == [
  518.             (cb, 'aaa')]:
  519.             raise AssertionError
  520.         del db.data_in[:]
  521.         if not db.lost == []:
  522.             raise AssertionError
  523.         ca.write('ccc')
  524.         cb.write('ddd')
  525.         sleep(1)
  526.         if not da.external_made == []:
  527.             raise AssertionError
  528.         if not da.data_in == [
  529.             (ca, 'ddd')]:
  530.             raise AssertionError
  531.         del da.data_in[:]
  532.         if not da.lost == []:
  533.             raise AssertionError
  534.         if not db.external_made == []:
  535.             raise AssertionError
  536.         if not db.data_in == [
  537.             (cb, 'ccc')]:
  538.             raise AssertionError
  539.         del db.data_in[:]
  540.         if not db.lost == []:
  541.             raise AssertionError
  542.         cb.close()
  543.         sleep(1)
  544.         if not da.external_made == []:
  545.             raise AssertionError
  546.         if not da.data_in == []:
  547.             raise AssertionError
  548.         if not da.lost == [
  549.             ca]:
  550.             raise AssertionError
  551.         del da.lost[:]
  552.         if not db.external_made == []:
  553.             raise AssertionError
  554.         if not db.data_in == []:
  555.             raise AssertionError
  556.         if not db.lost == []:
  557.             raise AssertionError
  558.     finally:
  559.         fa.set()
  560.         fb.set()
  561.  
  562.  
  563.  
  564. def test_connection_refused():
  565.     
  566.     try:
  567.         da = DummyHandler()
  568.         fa = Event()
  569.         sa = RawServer(fa, 100, 100)
  570.         loop(sa)
  571.         sl(sa, da, beginport + 6)
  572.         sleep(0.5)
  573.         ca = sa.start_connection(('127.0.0.1', beginport + 15))
  574.         sleep(1)
  575.         if not da.external_made == []:
  576.             raise AssertionError
  577.         if not da.data_in == []:
  578.             raise AssertionError
  579.         if not da.lost == [
  580.             ca]:
  581.             raise AssertionError
  582.         del da.lost[:]
  583.     finally:
  584.         fa.set()
  585.  
  586.  
  587.  
  588. def test_both_close():
  589.     
  590.     try:
  591.         da = DummyHandler()
  592.         fa = Event()
  593.         sa = RawServer(fa, 100, 100)
  594.         loop(sa)
  595.         sl(sa, da, beginport + 4)
  596.         sleep(1)
  597.         db = DummyHandler()
  598.         fb = Event()
  599.         sb = RawServer(fb, 100, 100)
  600.         loop(sb)
  601.         sl(sb, db, beginport + 5)
  602.         sleep(0.5)
  603.         ca = sa.start_connection(('127.0.0.1', beginport + 5))
  604.         sleep(1)
  605.         if not da.external_made == []:
  606.             raise AssertionError
  607.         if not da.data_in == []:
  608.             raise AssertionError
  609.         if not da.lost == []:
  610.             raise AssertionError
  611.         if not len(db.external_made) == 1:
  612.             raise AssertionError
  613.         cb = db.external_made[0]
  614.         del db.external_made[:]
  615.         if not db.data_in == []:
  616.             raise AssertionError
  617.         if not db.lost == []:
  618.             raise AssertionError
  619.         ca.write('aaa')
  620.         cb.write('bbb')
  621.         sleep(1)
  622.         if not da.external_made == []:
  623.             raise AssertionError
  624.         if not da.data_in == [
  625.             (ca, 'bbb')]:
  626.             raise AssertionError
  627.         del da.data_in[:]
  628.         if not da.lost == []:
  629.             raise AssertionError
  630.         if not db.external_made == []:
  631.             raise AssertionError
  632.         if not db.data_in == [
  633.             (cb, 'aaa')]:
  634.             raise AssertionError
  635.         del db.data_in[:]
  636.         if not db.lost == []:
  637.             raise AssertionError
  638.         ca.write('ccc')
  639.         cb.write('ddd')
  640.         sleep(1)
  641.         if not da.external_made == []:
  642.             raise AssertionError
  643.         if not da.data_in == [
  644.             (ca, 'ddd')]:
  645.             raise AssertionError
  646.         del da.data_in[:]
  647.         if not da.lost == []:
  648.             raise AssertionError
  649.         if not db.external_made == []:
  650.             raise AssertionError
  651.         if not db.data_in == [
  652.             (cb, 'ccc')]:
  653.             raise AssertionError
  654.         del db.data_in[:]
  655.         if not db.lost == []:
  656.             raise AssertionError
  657.         ca.close()
  658.         cb.close()
  659.         sleep(1)
  660.         if not da.external_made == []:
  661.             raise AssertionError
  662.         if not da.data_in == []:
  663.             raise AssertionError
  664.         if not da.lost == []:
  665.             raise AssertionError
  666.         if not db.external_made == []:
  667.             raise AssertionError
  668.         if not db.data_in == []:
  669.             raise AssertionError
  670.         if not db.lost == []:
  671.             raise AssertionError
  672.     finally:
  673.         fa.set()
  674.         fb.set()
  675.  
  676.  
  677.  
  678. def test_normal():
  679.     l = []
  680.     f = Event()
  681.     s = RawServer(f, 100, 100)
  682.     loop(s)
  683.     sl(s, DummyHandler(), beginport + 7)
  684.     s.add_task((lambda l = l: l.append('b')), 2)
  685.     s.add_task((lambda l = l: l.append('a')), 1)
  686.     s.add_task((lambda l = l: l.append('d')), 4)
  687.     sleep(1.5)
  688.     s.add_task((lambda l = l: l.append('c')), 1.5)
  689.     sleep(3)
  690.     if not l == [
  691.         'a',
  692.         'b',
  693.         'c',
  694.         'd']:
  695.         raise AssertionError
  696.     f.set()
  697.  
  698.  
  699. def test_catch_exception():
  700.     l = []
  701.     f = Event()
  702.     s = RawServer(f, 100, 100, False)
  703.     loop(s)
  704.     sl(s, DummyHandler(), beginport + 9)
  705.     s.add_task((lambda l = l: l.append('b')), 2)
  706.     s.add_task((lambda : 4 / 0), 1)
  707.     sleep(3)
  708.     if not l == [
  709.         'b']:
  710.         raise AssertionError
  711.     f.set()
  712.  
  713.  
  714. def test_closes_if_not_hit():
  715.     
  716.     try:
  717.         da = DummyHandler()
  718.         fa = Event()
  719.         sa = RawServer(fa, 2, 2)
  720.         loop(sa)
  721.         sl(sa, da, beginport + 14)
  722.         sleep(1)
  723.         db = DummyHandler()
  724.         fb = Event()
  725.         sb = RawServer(fb, 100, 100)
  726.         loop(sb)
  727.         sl(sb, db, beginport + 13)
  728.         sleep(0.5)
  729.         sa.start_connection(('127.0.0.1', beginport + 13))
  730.         sleep(1)
  731.         if not da.external_made == []:
  732.             raise AssertionError
  733.         if not da.data_in == []:
  734.             raise AssertionError
  735.         if not da.lost == []:
  736.             raise AssertionError
  737.         if not len(db.external_made) == 1:
  738.             raise AssertionError
  739.         del db.external_made[:]
  740.         if not db.data_in == []:
  741.             raise AssertionError
  742.         if not db.lost == []:
  743.             raise AssertionError
  744.         sleep(3.1000000000000001)
  745.         if not len(da.lost) == 1:
  746.             raise AssertionError
  747.         if not len(db.lost) == 1:
  748.             raise AssertionError
  749.     finally:
  750.         fa.set()
  751.         fb.set()
  752.  
  753.  
  754.  
  755. def test_does_not_close_if_hit():
  756.     
  757.     try:
  758.         fa = Event()
  759.         fb = Event()
  760.         da = DummyHandler()
  761.         sa = RawServer(fa, 2, 2)
  762.         loop(sa)
  763.         sl(sa, da, beginport + 12)
  764.         sleep(1)
  765.         db = DummyHandler()
  766.         sb = RawServer(fb, 100, 100)
  767.         loop(sb)
  768.         sl(sb, db, beginport + 13)
  769.         sleep(0.5)
  770.         sa.start_connection(('127.0.0.1', beginport + 13))
  771.         sleep(1)
  772.         if not da.external_made == []:
  773.             raise AssertionError
  774.         if not da.data_in == []:
  775.             raise AssertionError
  776.         if not da.lost == []:
  777.             raise AssertionError
  778.         if not len(db.external_made) == 1:
  779.             raise AssertionError
  780.         cb = db.external_made[0]
  781.         del db.external_made[:]
  782.         if not db.data_in == []:
  783.             raise AssertionError
  784.         if not db.lost == []:
  785.             raise AssertionError
  786.         cb.write('bbb')
  787.         sleep(0.5)
  788.         if not da.lost == []:
  789.             raise AssertionError
  790.         if not db.lost == []:
  791.             raise AssertionError
  792.     finally:
  793.         fa.set()
  794.         fb.set()
  795.  
  796.  
  797.